package com.kefu.call.task;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kefu.basic.service.BasicShareService;
import com.kefu.call.http.client.*;
import com.kefu.call.mapper.CallMakeCallMapper;
import com.kefu.call.model.CallMakeCall;
import com.kefu.call.vo.CallAgentMsgHangupPushVo;
import com.kefu.call.vo.CallAgentMsgPushVo;
import com.kefu.common.context.KefuContext;
import com.kefu.common.util.JacksonUtil;
import com.kefu.framework.security.KefuUserDetails;
import com.kefu.framework.spring.KefuApplicationContext;
import com.kefu.sys.model.SysTenant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Random;
import java.util.Set;

@Slf4j
@Component
@ConditionalOnProperty(prefix = "kefu.task.execute", name = "enabled", havingValue = "true", matchIfMissing = true)
public class CallAgentMsgPushTask {
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Resource
    RedisTemplate<String, Map<String, Object>> redisTemplate1;
    @Autowired
    BasicShareService basicShareService;
    @Autowired
    CallMakeCallMapper callMakeCallMapper;
    @Autowired
    CtiClient ctiClient;

    @Scheduled(fixedRate = 500)
    public void doWork() {
        Set<String> tokenSet = stringRedisTemplate.opsForSet().members("call:login_token_set");
        if (CollUtil.isNotEmpty(tokenSet)) {
            tokenSet.forEach(agentToken -> {
                ThreadUtil.execute(() -> {
                    try {
                        Map<String, Object> msgMap = redisTemplate1.opsForList().leftPop("call_event_msg_list:" + agentToken);
                        KefuUserDetails userDetails = null;
                        try {
                            ResourceServerTokenServices tokenServices = KefuApplicationContext.getBean(ResourceServerTokenServices.class);
                            OAuth2Authentication auth = tokenServices.loadAuthentication(agentToken);
                            userDetails = (KefuUserDetails) auth.getPrincipal();
                        }catch (Exception e){
                        }
                        if(userDetails==null){
                            stringRedisTemplate.opsForSet().remove("call:login_token_set", agentToken);
                            log.info("login_token_set_remove:{}",agentToken);
                        }
                        if (msgMap != null) {
                            log.info("callAgentMsgPushTask_msgMap:{},{}", agentToken, msgMap);
                            String eventTypeCti = String.valueOf(msgMap.get("event_type"));
                            //sip话机下线，把坐席签出
                            if (eventTypeCti.equals("1501")) {
                                if (userDetails != null) {
                                    KefuContext.getKefuContext().setTenantId(userDetails.getTenantId());
                                    ctiClient.agentLogout(agentToken);
                                    log.info("logout_by_sipout:{}", agentToken);
                                }
                            }
                            if (eventTypeCti.equals("1401") || eventTypeCti.equals("1404") || eventTypeCti.equals("1405")) {
                                CallAgentMsgPushVo pushVo = new CallAgentMsgPushVo();
                                pushVo.setEventTime(String.valueOf(msgMap.get("event_time")));
                                pushVo.setCallId(String.valueOf(msgMap.get("calluuid")));
                                pushVo.setCustomerNumber(String.valueOf(msgMap.get("customer_number")));
                                pushVo.setOtherText(String.valueOf(msgMap.get("variable_otherText")));
                                if (userDetails != null) {
                                    pushVo.setTenantId(userDetails.getTenantId());
                                    pushVo.setAgentId(userDetails.getUserId());
                                    pushVo.setAgentJobno(userDetails.getUserJobno());
                                }
                                String eventType = eventTypeCti.equals("1401") ? "1" : eventTypeCti.equals("1404") ? "2" : "3";
                                pushVo.setEventType(eventType);
                                if (eventType.equals("3")) {
                                    ThreadUtil.sleep(1000);
                                    CallMakeCall callDb = callMakeCallMapper.selectOne(Wrappers.lambdaQuery(CallMakeCall.class)
                                            .eq(CallMakeCall::getCallId, pushVo.getCallId()).orderByDesc(CallMakeCall::getRingTime).last("limit 1"));
                                    CallAgentMsgHangupPushVo hangupPushVo = BeanUtil.toBean(callDb, CallAgentMsgHangupPushVo.class);
                                    hangupPushVo.setStartTime(callDb.getRingTime());
                                    hangupPushVo.setHangUpTime(callDb.getCallHangupTime());
                                    pushVo.setHangupPushVo(hangupPushVo);
                                }
                                SysTenant sysTenant = basicShareService.getTenantCache(pushVo.getTenantId());
                                String url = sysTenant.getPushCallAgent();
                                String nonce = String.valueOf(new Random().nextInt(9999));
                                String time = String.valueOf(System.currentTimeMillis());
                                String sign = SecureUtil.sha1(sysTenant.getAppSecret() + nonce + time);
                                String json = JacksonUtil.toString(pushVo);
                                String result = HttpUtil.createPost(url)
                                        .header("tenant", sysTenant.getTenantId())
                                        .header("nonce", nonce)
                                        .header("time", time)
                                        .header("sign", sign)
                                        .header("type", "call_agent_event")
                                        .body(json).execute().body();
                                log.info("push_call_agent_event:{},{},{},{},{},{},{}", url, agentToken, nonce, time, sign, json, result);
                            }
                        }
                    } catch (Exception e) {
                        log.error("CallAgentMsgPushTask_程序异常", e);
                    }
                });
            });
        }
    }

}
